module FuelPricesEurope

  class TableParser

    def initialize(table)
      @table = table
      @headings = []
      @countries = []
      @results = {}
    end

    def parse
      @table.css('tr').each_with_index do |row, row_index|
        parse_row(row, row_index)
      end
      format_results
    end

    def parse_row(row, row_index)
      if row_index > 0
        country = row.css('td')[2].text.downcase
        @countries << country
        @results[country] = {}
        row.css('td').each_with_index do |col, col_index|
          parse_column(country, col, col_index)
        end
      else
        parse_heading(row)
      end
    end

    def parse_heading(row)
      row.css('td').each_with_index do |col, col_index|
        if col_index > 0
          @headings << col.at_css('b').text.downcase
        end
      end
    end

    def parse_column(country, col, col_index)
      if col_index > 0
        @results[country][@headings[col_index - 1]] = col.text
      end
    end

    # Format the parsed results
    def format_results
      data = {}
      @results.each do |country_name, result|
        country = Country.find_country_by_name(country_name)
        unless country.nil?
          data[country.alpha2] = create_country_data(country, result)
        end
      end
      data
    end

    # Create a country data object
    def create_country_data(country, result)
      date_format = '%B %d, %Y'
      country_data = CountryData.new
      country_data.country = country
      country_data.record_date = DateTime.strptime(result['record date'], date_format)
      country_data.lpg_nozzle = result['lpg nozzle'].downcase == 'unknown' ? nil : result['lpg nozzle'].downcase
      country_data.lpg_stations = result['lpg stations'].downcase == 'unknown' ? nil : result['lpg stations'].to_i

      add_price_fields(country_data, result)
    end

    # Add all the price fields to the country_data object
    def add_price_fields(country_data, result)
      gasoline_price = parse_price_field(result['unleaded 95 ron'])
      diesel_price = parse_price_field(result['diesel'])
      lpg_price = parse_price_field(result['lpg'])

      country_data.gasoline_price = gasoline_price[:euro]
      country_data.gasoline_price_local = gasoline_price[:local] unless gasoline_price[:local].nil?
      country_data.diesel_price = diesel_price[:euro]
      country_data.diesel_price_local = diesel_price[:local] unless diesel_price[:local].nil?
      country_data.lpg_price = lpg_price[:euro]
      country_data.lpg_price_local = lpg_price[:local] unless lpg_price[:local].nil?
      country_data
    end

    # Parse price fields
    def parse_price_field(value)
      splitted = value.strip.gsub(/\s+/, ' ').gsub(',', '.').split(/\s+/)
      result = {euro: splitted[1].to_f}
      unless splitted[2].to_s.empty? && splitted[3].to_s.empty?
        result[:local] = {currency: splitted[2], value: splitted[3].to_f}
      end
      result
    end
  end
end